#ifndef _DEFINES_H_

#define _DEFINES_H_

/*
 * Standard gettext macros.
 */
#ifdef ENABLE_NLS
#  include <libintl.h>
#  undef _
#  define _(String) dgettext (PACKAGE, String)
#  define Q_(String) g_strip_context ((String), gettext (String))
#  ifdef gettext_noop
#    define N_(String) gettext_noop (String)
#  else
#    define N_(String) (String)
#  endif
#else
#  define textdomain(String) (String)
#  define gettext(String) (String)
#  define dgettext(Domain,Message) (Message)
#  define dcgettext(Domain,Message,Type) (Message)
#  define bindtextdomain(Domain,Directory) (Domain)
#  define _(String) (String)
#  define Q_(String) g_strip_context ((String), (String))
#  define N_(String) (String)
#endif

	#include <string.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <unistd.h>
	#include <glib.h>
	#include <gtk/gtk.h>
	#include <libxml/xmlreader.h>
	#include <glade/glade.h>
	#include <sys/types.h>
	#include <pwd.h>
	#include <wait.h>

#ifndef OUT
	#define OUT
#endif

#ifndef IN
	#define IN const
#endif

	#define MAX_PATH		265
	#define TITLE_LENGTH	256
	#define ARTIST_LENGTH	256
	struct _SongInfo {
		gchar szSongFolder[MAX_PATH]; // 歌词文件完整路径名
		gchar szLyricFileName[MAX_PATH]; // 歌词文件名
		gchar szFileName[MAX_PATH];		 // 歌曲文件名
		gchar szTitle[MAX_PATH];		 // 歌曲名
		gchar szArtist[MAX_PATH];		 // 歌手名
	};
	typedef struct _SongInfo SongInfo;
	
	struct _AppInfo {
		gchar szName[MAX_PATH];
		gchar szApp[MAX_PATH];
	};
	typedef struct _AppInfo AppInfo;

	struct _Configs {
		gboolean bShowWindowLyric;
		struct {
			GdkColor background; // 背景颜色
			GdkColor normal;	 // 普通歌词颜色
			GdkColor current;	 // 当前歌词颜色
			GdkColor drag;		 // 拖动中歌词颜色
			GdkColor msg;		 // 消息颜色
			GdkColor error;		 // 错误信息颜色
		}colors;
		gchar szLyricPath[MAX_PATH]; // 保存歌词的目录
		gboolean bSaveLyricToSongFolder; // 是否保存歌词到歌曲所在目录
		gboolean bSaveLyricAsFileName; // 是否保存歌词到歌曲所在目录
		gboolean bSmartShowWin;		 // 是否智能显示窗口
		gboolean bSmartDownLoad;	 // 是否智能下载
		gboolean iOpacity;			 // 窗口透明度
		gboolean bCanDrag;			 // 可以拖动歌词
		gboolean bChangeLyric;	 	 // 可以通过鼠标滚轮修改歌词
		gboolean bAutoSaveLyric; 	 // 如果歌词被修改是否自动保存（切换歌词时保存）
		gboolean bShowBroad;		 // 是否显示窗口装饰
		gboolean bShowOSDLyric;		 // 是否显示OSD歌词
		gboolean bIsKaLaOK;		 	 // 是否以卡拉OK样式显示歌词
		struct {
			gchar fake_translucent_bg[MAX_PATH];
			gchar vposition[MAX_PATH];
			gchar halignment[MAX_PATH];
			gchar animations[MAX_PATH];
			gchar szFontName[MAX_PATH];
		}OSD;
		gchar szLyricFontName[MAX_PATH];// 歌词字体的名字
		gchar szLyricEncode[MAX_PATH]; 	// 歌词字体的名字
		gint nSearchAppIndex; 			// 使用哪一个搜索引擎
		struct {
			int iX;		// 窗口的X坐标
			int iY;		// 窗口的Y坐标
		}pos;
	};
	typedef struct _Configs Configs;
	
	struct _Player {
		// 获取配置信息
		gboolean (*LoadConfigs)(OUT Configs * pConfigs);
		// 保存配置信息
		gboolean (*SaveConfigs)(IN Configs * pConfigs);
		// 获取当前时间
		gint (*GetCurrTime)();
		// 获取当前时间
		gint (*GetSongTime)();
		// 获取歌曲信息
		gboolean (*GetSongInfo)(SongInfo * pInfo);
		// 是否是当前正在播放的歌曲
		gboolean (*IsCurrSong)(SongInfo info);
		// 转换字符串到UTF-8
		gchar *(*Str2UTF8)(const gchar * lpszStr);

		// 搜索引擎
		gint (*GetSearchAppCount)();
		gboolean (*GetSearchApp)(gint nIndex, AppInfo* pApp);
		gboolean (*SetSearchApp)(gint nIndex, AppInfo app);
	};
	
	enum AppState {
		AS_Waiting		= 0,	// 等待
		AS_LoadingLyric = 1,	// 正在加载歌词
		AS_SearchingLyric = 2,	// 正在搜索歌词
		AS_DowningLyric = 3,	// 正在下载歌词
		AS_ShowingLyric = 4,	// 正在显示歌词
		AS_DrapingLyric = 5,	// 正在拖动歌词
		AS_EditingLyric = 6		// 正在编辑歌词
	};
	
	struct _EditLyricDlg {
		char m_szLyricFile[MAX_PATH];
		GladeXML *m_pEditLyricXML;
		gboolean m_bModfiy;
		gboolean m_bEditing;
		
		void (*RefreshState)();
		void (*EditLyric)();
	};
	typedef struct _EditLyricDlg EditLyricDlg;
	
	// 歌词窗口，提供歌词的显示和编辑功能
	struct _LyricWnd {
		GtkWidget *pThis;
		void (*RefreshLyricSetting)();
		void (*ShowLyric)();
		void (*SmartShowWnd)(gboolean bShow);
		void (*ClearLyric)();
		gboolean (*ParseLyric)(gchar* lpszLyricFileName);
		GList* m_ListCurrLyric;	//LyricItem
		GList* _m_current;
		guint m_TimerId;
		
		gboolean m_bLyricChanging;
		gboolean m_bLyricChanged;
		gboolean m_bScrollMouseChange;
		
		EditLyricDlg m_EditLyricDlg;
	};
	typedef struct _LyricWnd LyricWnd;
	
	struct _ShowLyricApp {
		// 初始化
		void (*Init)();
		// 清空资源
		void (*Clean)();
		// 显示配置对话框
		void (*ShowConfigDlg)();
		// 更新配置信息
		void (*UpdataSetting)();
		// 切换歌曲前，返回false表示没有找到歌词（本地和网上都没有找到）
		gboolean (*PreChangeSong)(SongInfo* info);
		// 切换歌曲
		void (*ChangeSong)(SongInfo info);
		// 关于
		void (*About)(GtkWindow* pParent);
		// 获取默认配置值
		void (*GetDefautConfigs)(Configs* pConfig);
		
		struct _Player m_player;
		struct _Configs m_configs;	// 配置信息
		enum AppState m_state;		// 程序的状态
		
		LyricWnd m_LyricWnd;
		
		gchar m_szCurrUsrPath[MAX_PATH];
		gchar m_szConfigPath[MAX_PATH];
		SongInfo m_CurrSongInfo;
		
		GladeXML *m_xml;
	};
	extern struct _ShowLyricApp theApp;
	
	typedef struct {
		int		iTime;
		gchar*	lpszValue;
		int bShowing;
	}LyricItem;
	
	typedef struct {
		int index;
		gchar szID[MAX_PATH];
		gchar szArtist[MAX_PATH];
		gchar szTitle[MAX_PATH];
	}LyricsListItem;

#define GLADE_FILE "/usr/share/ShowLyric/ShowLyricUI.glade"
#define SEL_LYRIC_GLADE_FILE "/usr/share/ShowLyric/SelLyricDlg.glade"
#define CONFIG_GLADE_FILE "/usr/share/ShowLyric/ConfigDlg.glade"

#define XML_CONNECT_SIGNAL(XML, id, Fun, DATA) glade_xml_signal_connect_data(XML, #id,\
			G_CALLBACK(Fun), DATA)
#define XML_CONNECT_SIGNAL2(XML, id, DATA) XML_CONNECT_SIGNAL(XML, id, id, DATA)

#define CONNECT_SIGNAL(WND, ID, Fun, DATA) g_signal_connect(G_OBJECT (WND), #ID,\
							G_CALLBACK (Fun), DATA)
#endif
